'use strict';

const pkgDir = require('pkg-dir').sync;
const path = require('path');
const pathExists = require('path-exists').sync;
const npminstall = require('npminstall');
const fse = require('fs-extra');
const {isObject} = require('@test-hy-in/utils');
const formatPath = require('@test-hy-in/format-path');
const {getDefaultRegistry,getNpmLatestVersion} = require('@test-hy-in/get-npm-info');

class Package {
    constructor(options){
        if(!options){
            throw new Error('Package类的options参数不能为空！')
        };
        if(!isObject(options)){
            throw new Error('Package类的options参数必须为对象！')
        };
        this.targetPath = options.targetPath;
        this.storeDir = options.storeDir;
        this.packageName = options.packageName;
        this.packageVersion = options.packageVersion;
        // 缓存文件的name路径格式转换
        this.cacheFilePathPrefix = this.packageName.replace('/','_');
    };
    // 缓存的文件路径
    get cacheFilePath(){
        return path.resolve(this.storeDir,`_${this.cacheFilePathPrefix}@${this.packageVersion}@${this.packageName}`);
    };
    // 指定包版本来生成对应路径
    getSpecificCacheFilePath(packageVersion){
        return path.resolve(this.storeDir,`_${this.cacheFilePathPrefix}@${packageVersion}@${this.packageName}`);
    };
    async prepare(){
        if(this.storeDir&&!pathExists(this.storeDir)){
            // 自动创建目录
            fse.mkdirpSync(this.storeDir)
        };
        if(this.packageVersion==='latest'){
            this.packageVersion = await getNpmLatestVersion(this.packageName);
        }
    };
    // 判断当前package是否存在
    async exists(){
        if(this.storeDir){
            await this.prepare();
            return pathExists(this.cacheFilePath)
        }else{
            return pathExists(this.targetPath)
        }
    };
    // 不存在则安装package
    async install(){
        await this.prepare();
        return npminstall({
            root:this.targetPath,
            storeDir:this.storeDir,
            registry:getDefaultRegistry(),
            pkgs:[{
                name:this.packageName,
                version:this.packageVersion
            }]
        })
    };
    // 版本低更新package
    async updata(){
        await this.prepare();
        // 1、获取最新npm模块版本号
        const latespackageVersion = await getNpmLatestVersion(this.packageName);
        // 2、查询最新版本号对应的路径是否存在
        const latestFilePath = this.getSpecificCacheFilePath(latespackageVersion);
        // 3、如果不存在，则直接安装最新版本号
        if(!pathExists(latestFilePath)){
            await npminstall({
                root:this.targetPath,
                storeDir:this.storeDir,
                registry:getDefaultRegistry(),
                pkgs:[{
                    name:this.packageName,
                    version:latespackageVersion
                }]
            });
            this.packageVersion = latespackageVersion
        }else{
            this.packageVersion = latespackageVersion
        }
    };
    // 获取入口文件路径
    getRootFilePath(){
        function _getRootFile(targetPath){
            // 1、获取packgae.json所在的目录
            // 2、读取main/bin对应的入口文件路径
            // 3、对路径做兼容处理（win、macos）
            const dir = pkgDir(targetPath);
            if(dir){
                const pkgFile = require(path.resolve(dir,'package.json'));
                if(pkgFile&&pkgFile.main){
                    return formatPath(path.resolve(dir,pkgFile.main))
                }
            }
            return null
        }
        if(this.storeDir){
            return _getRootFile(this.cacheFilePath)
        }else{
            return _getRootFile(this.targetPath)
        }
    }
}

module.exports = Package;